home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / sun / volume1 / tooltool2.1c / part07 < prev    next >
Encoding:
Internet Message Format  |  1989-06-06  |  41.6 KB

  1. Path: uunet!husc6!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew
  2. From: mcgrew@dartagnan.rutgers.edu (Charles Mcgrew)
  3. Newsgroups: comp.sources.sun
  4. Subject: v01i026:  Tooltool - a suntools user interface builder, Part 07/13
  5. Message-ID: <Jun.7.00.19.39.1989.23621@dartagnan.rutgers.edu>
  6. Date: 7 Jun 89 04:19:43 GMT
  7. Organization: Rutgers Univ., New Brunswick, N.J.
  8. Lines: 1430
  9. Approved: mcgrew@aramis.rutgers.edu
  10.  
  11. Submitted-by: Chuck Musciano <chuck@trantor.harris-atd.com>
  12. Posting-number: Volume 1, Issue 26
  13. Archive-name: tooltool2.1c/part07
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 7 (of 13)."
  22. # Contents:  objects.c samples/vt100/out.c
  23. # Wrapped by chuck@melmac on Thu Jun  1 10:39:33 1989
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'objects.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'objects.c'\"
  27. else
  28. echo shar: Extracting \"'objects.c'\" \(19133 characters\)
  29. sed "s/^X//" >'objects.c' <<'END_OF_FILE'
  30. X/************************************************************************/
  31. X/*    Copyright 1988 by Chuck Musciano and Harris Corporation        */
  32. X/*                                    */
  33. X/*    Permission to use, copy, modify, and distribute this software    */
  34. X/*    and its documentation for any purpose and without fee is    */
  35. X/*    hereby granted, provided that the above copyright notice    */
  36. X/*    appear in all copies and that both that copyright notice and    */
  37. X/*    this permission notice appear in supporting documentation, and    */
  38. X/*    that the name of Chuck Musciano and Harris Corporation not be    */
  39. X/*    used in advertising or publicity pertaining to distribution    */
  40. X/*    of the software without specific, written prior permission.    */
  41. X/*    Chuck Musciano and Harris Corporation make no representations    */
  42. X/*    about the suitability of this software for any purpose.  It is    */
  43. X/*    provided "as is" without express or implied warranty.        */
  44. X/*                                    */
  45. X/*    The sale of any product based wholely or in part upon the     */
  46. X/*    technology provided by tooltool is strictly forbidden without    */
  47. X/*    specific, prior written permission from Harris Corporation.    */
  48. X/*    Tooltool technology includes, but is not limited to, the source    */
  49. X/*    code, executable binary files, specification language, and    */
  50. X/*    sample specification files.                    */
  51. X/************************************************************************/
  52. X
  53. X
  54. X#include    <ctype.h>
  55. X
  56. X#include    "tooltool.h"
  57. X
  58. XPRIVATE    short    cross_bits[] = {0x4000, 0xe000, 0x4000};
  59. Xmpr_static(tt_better_button_cross, 3, 3, 1, cross_bits);
  60. X
  61. XPRIVATE    short    arrow_bits[] = {0x0400, 0x0600, 0xFD00, 0x0180, 0xFD00, 0x0600, 0x0400};
  62. Xmpr_static(tt_menu_arrow, 9, 7, 1, arrow_bits);
  63. X
  64. XPUBLIC    event_proc(),
  65. X    notify_proc();
  66. X
  67. X/************************************************************************/
  68. X/* This group of routines contructs individual panel gadgets.        */
  69. X/************************************************************************/
  70. X
  71. X/************************************************************************/
  72. XPRIVATE    struct    pixrect    *better_menu_image(text, chars, pixels, font)
  73. X
  74. Xchar    *text;
  75. Xint    chars;
  76. Xint    pixels;
  77. Xstruct    pixfont    *font;
  78. X
  79. X{    struct    pixrect    *pr;
  80. X    struct    pr_prpos    pos;
  81. X    int    width, true_width, height;
  82. X
  83. X    width = chars * charwidth_of(font) + pixels;
  84. X    true_width = text_width(text, font) + 13;
  85. X    if (width < true_width)
  86. X       width = true_width;
  87. X    pr = mem_create(width + 8, height = charheight_of(font) + 6, 1);
  88. X    pr_rop(pr, 0, 0, width + 8, height, PIX_SRC | PIX_COLOR(1), NULL, 0, 0);
  89. X    pr_rop(pr, 2, 2, width + 4, height - 4, PIX_SRC | PIX_COLOR(0), NULL, 0, 0);
  90. X    pr_rop(pr, width - 5, (height - 7) / 2, 9, 7, PIX_SRC, &tt_menu_arrow, 0, 0);
  91. X    pos.pr = pr;
  92. X    pos.pos.x = 4 + (width - true_width) / 2;
  93. X    pos.pos.y = 4 + baseline_of(font);
  94. X    pf_ttext(pos, PIX_SRC | PIX_COLOR(1), font, text);
  95. X    return(pr);
  96. X}
  97. X
  98. X/************************************************************************/
  99. XPRIVATE    struct    pixrect    *better_button_image(text, chars, pixels, font)
  100. X
  101. Xchar    *text;
  102. Xint    chars;
  103. Xint    pixels;
  104. Xstruct    pixfont    *font;
  105. X
  106. X{    struct    pixrect    *pr;
  107. X    struct    pr_prpos    pos;
  108. X    int    width, true_width, height;
  109. X
  110. X    width = chars * charwidth_of(font) + pixels;
  111. X    true_width = text_width(text, font);
  112. X    if (width < true_width)
  113. X       width = true_width;
  114. X    pr = mem_create(width + 8, height = charheight_of(font) + 6, 1);
  115. X    pr_rop(pr, 3, 0, width + 2, 2, PIX_SRC | PIX_COLOR(1), NULL, 0, 0);
  116. X    pr_rop(pr, 3, height - 2, width + 2, 2, PIX_SRC | PIX_COLOR(1), NULL, 0, 0);
  117. X    pr_rop(pr, 0, 3, 2, height - 6, PIX_SRC | PIX_COLOR(1), NULL, 0, 0);
  118. X    pr_rop(pr, width + 6, 3, 2, height - 6, PIX_SRC | PIX_COLOR(1), NULL, 0, 0);
  119. X    pr_rop(pr, 1, 1, 3, 3, PIX_SRC | PIX_DST, &tt_better_button_cross, 0, 0);
  120. X    pr_rop(pr, width + 4, 1, 3, 3, PIX_SRC | PIX_DST, &tt_better_button_cross, 0, 0);
  121. X    pr_rop(pr, width + 4, height - 4, 3, 3, PIX_SRC | PIX_DST, &tt_better_button_cross, 0, 0);
  122. X    pr_rop(pr, 1, height - 4, 3, 3, PIX_SRC | PIX_DST, &tt_better_button_cross, 0, 0);
  123. X    pos.pr = pr;
  124. X    pos.pos.x = 4 + (width - true_width) / 2;
  125. X    pos.pos.y = 4 + baseline_of(font);
  126. X    pf_ttext(pos, PIX_SRC | PIX_COLOR(1), font, text);
  127. X    return(pr);
  128. X}
  129. X
  130. X/************************************************************************/
  131. XPRIVATE    image_box(gadget)
  132. X
  133. Xg_ptr    gadget;
  134. X
  135. X{    int    w, h, mw, mh;
  136. X    cv_ptr    cv;
  137. X    double    log10();
  138. X
  139. X    if (gadget->kind == GADGET_BUTTON) {
  140. X       if (gadget->u.but.label[0]->is_icon) {
  141. X          gadget->image = gadget->u.but.label[0]->image;
  142. X          gadget->width = gadget->image->pr_width;
  143. X          gadget->height = gadget->image->pr_height;
  144. X          }
  145. X       else {
  146. X          gadget->width = text_width(gadget->u.but.label[0]->label, gadget->u.but.label[0]->font) + 8;
  147. X          gadget->height = charheight_of(gadget->u.but.label[0]->font) + 6;
  148. X          }
  149. X       }
  150. X    else if (gadget->kind == GADGET_MENU) {
  151. X       if (gadget->u.men.label->is_icon) {
  152. X          gadget->image = gadget->u.men.label->image;
  153. X          gadget->width = gadget->image->pr_width;
  154. X          gadget->height = gadget->image->pr_height;
  155. X          }
  156. X       else {
  157. X          gadget->width = text_width(gadget->u.men.label->label, gadget->u.men.label->font) + 21;
  158. X          gadget->height = charheight_of(gadget->u.men.label->font) + 6;
  159. X          }
  160. X       }
  161. X    else if (gadget->kind == GADGET_LABEL) {
  162. X       tt_construct_label(gadget->u.lab.label);
  163. X       gadget->image = gadget->u.lab.label->image;
  164. X       gadget->width = gadget->image->pr_width;
  165. X       gadget->height = gadget->image->pr_height;
  166. X       }
  167. X    else if (gadget->kind == GADGET_CHOICE) {
  168. X       if (gadget->u.cho.label == NULL) {
  169. X          gadget->width = -4; /* hack: correct for 4 pixel offset below */
  170. X          gadget->height = 0;
  171. X          }
  172. X       else {
  173. X          tt_construct_label(gadget->u.cho.label);
  174. X          gadget->image = gadget->u.cho.label->image;
  175. X          gadget->width = gadget->u.cho.label->image->pr_width;
  176. X          gadget->height = gadget->u.cho.label->image->pr_height;
  177. X          }
  178. X       tt_construct_label(gadget->u.cho.mark);
  179. X       tt_construct_label(gadget->u.cho.nomark);
  180. X       mw = max(gadget->u.cho.mark->image->pr_width, gadget->u.cho.nomark->image->pr_width);
  181. X       mh = max(gadget->u.cho.mark->image->pr_height, gadget->u.cho.nomark->image->pr_height);
  182. X       for (w = h = 0, cv = gadget->u.cho.value; cv; cv = cv->next) {
  183. X          tt_construct_label(cv->label);
  184. X          switch (gadget->u.cho.mode) {
  185. X             case CHOICE_CURRENT    : 
  186. X             case CHOICE_CYCLE      : h = max(cv->label->image->pr_height, h);
  187. X                          w = max(cv->label->image->pr_width, w);
  188. X                          break;
  189. X             case CHOICE_VERTICAL   : h += max(cv->label->image->pr_height, mh) + 4;
  190. X                          w = max(cv->label->image->pr_width, w);
  191. X                          break;
  192. X             case CHOICE_HORIZONTAL : h = max(cv->label->image->pr_height, h);
  193. X                          w += cv->label->image->pr_width + mw + 8;
  194. X                          break;
  195. X         }
  196. X          }
  197. X       switch (gadget->u.cho.mode) {
  198. X          case CHOICE_CURRENT    : gadget->width += w + 4;
  199. X                             gadget->height = max(gadget->height, h);
  200. X                       break;
  201. X          case CHOICE_CYCLE      : gadget->width += w + mw + 8;
  202. X                             gadget->height = max(gadget->height, h);
  203. X                             gadget->height = max(gadget->height, mh);
  204. X                       break;
  205. X          case CHOICE_VERTICAL   : gadget->width += w + mw + 8;
  206. X                             gadget->height = max(gadget->height, h - 4);
  207. X                       break;
  208. X          case CHOICE_HORIZONTAL : gadget->width += w;
  209. X                       gadget->height = max(gadget->height, h);
  210. X                       break;
  211. X          }
  212. X       gadget->u.cho.ch_width = w;
  213. X       gadget->u.cho.ch_height = h;
  214. X       }
  215. X    else if (gadget->kind == GADGET_SLIDER) {
  216. X       if (gadget->u.sli.label == NULL) {
  217. X          gadget->width = -4; /* hack: correct for 4 pixel offset below */
  218. X          gadget->height = 0;
  219. X          }
  220. X       else {
  221. X          tt_construct_label(gadget->u.sli.label);
  222. X          gadget->image = gadget->u.sli.label->image;
  223. X          gadget->width = gadget->u.sli.label->image->pr_width;
  224. X          gadget->height = gadget->u.sli.label->image->pr_height;
  225. X          }
  226. X       gadget->height = max(gadget->height, charheight_of(gadget->u.sli.font));
  227. X       gadget->width += 10 + gadget->u.sli.width;
  228. X       w = max(((int) log10(abs(gadget->u.sli.minimum) + 0.1)), ((int) log10(abs(gadget->u.sli.maximum) + 0.1))) + 1;
  229. X       if (gadget->u.sli.minimum < 0 || gadget->u.sli.maximum < 0)
  230. X          w++;
  231. X       if (gadget->u.sli.range)
  232. X          gadget->width += (2 * w + 2) * charwidth_of(gadget->u.sli.font);
  233. X       if (gadget->u.sli.value)
  234. X          gadget->width += (w + 3) * charwidth_of(gadget->u.sli.font);
  235. X       }
  236. X    else if (gadget->kind == GADGET_TEXT) {
  237. X       if (gadget->u.tex.label == NULL) {
  238. X          gadget->width = -4; /* hack: correct for 4 pixel offset below */
  239. X          gadget->height = 0;
  240. X          }
  241. X       else {
  242. X          tt_construct_label(gadget->u.tex.label);
  243. X          gadget->image = gadget->u.tex.label->image;
  244. X          gadget->width = gadget->u.tex.label->image->pr_width;
  245. X          gadget->height = gadget->u.tex.label->image->pr_height;
  246. X          }
  247. X       gadget->width += 4 + gadget->u.tex.display_len * charwidth_of(gadget->u.tex.font);
  248. X       gadget->height = max(charheight_of(gadget->u.tex.font), gadget->height);
  249. X       }
  250. X}
  251. X
  252. X/************************************************************************/
  253. XEXPORT    tt_build_images(d)
  254. X
  255. Xd_ptr    d;
  256. X
  257. X{    int    i, len = 0;
  258. X    g_ptr    b;
  259. X    char    *p;
  260. X
  261. X    for (b = d->gadgets; b; b = b->next) {
  262. X       image_box(b);
  263. X       if (b->kind == GADGET_BUTTON || b->kind == GADGET_MENU)
  264. X          len = (b->width > len)? b->width : len;
  265. X       }
  266. X    if (d->proportional)
  267. X       len = 0;
  268. X    for (b = d->gadgets; b; b = b->next) {
  269. X       if (b->kind == GADGET_BUTTON) {
  270. X          if (b->image == NULL) {
  271. X             b->image = better_button_image(b->u.but.label[0]->label, 0, len - 8, b->u.but.label[0]->font);
  272. X             b->width = b->image->pr_width;
  273. X             b->height = b->image->pr_height;
  274. X             }
  275. X          b->u.but.menu = menu_create(0);
  276. X          for (i = 0; i < MAX_SHIFT_SETS; i++)
  277. X             if (b->u.but.label[i])
  278. X                if (b->u.but.label[i]->is_icon) {
  279. X                   menu_set(b->u.but.menu,
  280. X                              MENU_APPEND_ITEM, menu_create_item(MENU_IMAGE_ITEM, b->u.but.label[i]->image, b->u.but.action[i],
  281. X                                                    0),
  282. X                           0);
  283. X                   }
  284. X                else {
  285. X                   p = (char *) safe_malloc(strlen(b->u.but.label[i]->label) + 5);
  286. X                   strcpy(p, "    ");
  287. X                   strcat(p, b->u.but.label[i]->label);
  288. X                   if (i & S_SHIFT)
  289. X                      p[0] = 'S';
  290. X                   if (i & S_CONTROL)
  291. X                      p[1] = 'C';
  292. X                   if (i & S_META)
  293. X                      p[2] = 'M';
  294. X                   menu_set(b->u.but.menu,
  295. X                              MENU_APPEND_ITEM, menu_create_item(MENU_STRING_ITEM, p, b->u.but.action[i],
  296. X                                                 MENU_FONT, b->u.but.label[i]->font,
  297. X                                                 0),
  298. X                           0);
  299. X                   }
  300. X          }
  301. X       else if (b->kind == GADGET_MENU) {
  302. X          if (b->image == NULL) {
  303. X             b->image = better_menu_image(b->u.men.label->label, 0, len - 8, d->g_font);
  304. X             b->width = b->image->pr_width;
  305. X             b->height = b->image->pr_height;
  306. X             }
  307. X          }
  308. X       else if (b->kind == GADGET_LABEL) {
  309. X          /* do nothing, image_box took care of it */
  310. X          }
  311. X       else if (b->kind == GADGET_TEXT) {
  312. X          /* do nothing, image_box took care of it */
  313. X          }
  314. X       else if (b->kind == GADGET_CHOICE) {
  315. X          /* do nothing, image_box took care of it */
  316. X          }
  317. X       else if (b->kind == GADGET_SLIDER) {
  318. X          /* do nothing, image_box took care of it */
  319. X          }
  320. X       }
  321. X}
  322. X
  323. X/************************************************************************/
  324. XEXPORT    tt_make_gadget(d, gadget, x, y)
  325. X
  326. Xd_ptr    d;
  327. Xg_ptr    gadget;
  328. Xint    x;
  329. Xint    y;
  330. X
  331. X{    char    *s;
  332. X    int    i, lx, ly, mx, my, vx, vy, max_h, max_mh, max_mw;
  333. X    Panel_item    p;
  334. X    cv_ptr    cv;
  335. X
  336. X    if (gadget->x != -1) {
  337. X       x = gadget->x;
  338. X       y = gadget->y;
  339. X       }
  340. X    if (gadget->kind == GADGET_BUTTON || gadget->kind == GADGET_MENU)
  341. X       p = panel_create_item(d->panel, (gadget->kind == GADGET_BUTTON)? PANEL_BUTTON : PANEL_MESSAGE,
  342. X                    PANEL_LABEL_IMAGE, gadget->image,
  343. X                    PANEL_ITEM_X, x,
  344. X                    PANEL_ITEM_Y, y,
  345. X                    PANEL_CLIENT_DATA, gadget,
  346. X                    PANEL_EVENT_PROC, event_proc,
  347. X                    PANEL_NOTIFY_PROC, notify_proc,
  348. X                    PANEL_ACCEPT_KEYSTROKE, !d->text_items_exist,
  349. X                 0);
  350. X    else if (gadget->kind == GADGET_LABEL)
  351. X       p = panel_create_item(d->panel, PANEL_MESSAGE,
  352. X                    PANEL_LABEL_IMAGE, gadget->image,
  353. X                    PANEL_ITEM_X, x,
  354. X                    PANEL_ITEM_Y, y,
  355. X                    PANEL_CLIENT_DATA, gadget,
  356. X                    PANEL_EVENT_PROC, event_proc,
  357. X                    PANEL_NOTIFY_PROC, notify_proc,
  358. X                    PANEL_ACCEPT_KEYSTROKE, !d->text_items_exist,
  359. X                 0);
  360. X    else if (gadget->kind == GADGET_SLIDER) {
  361. X       if (gadget->u.sli.label == NULL)
  362. X          /* do nothing */ ;
  363. X       else if (gadget->u.sli.label->image->pr_height > charheight_of(gadget->u.sli.font)) {
  364. X          ly = y;
  365. X          vy = y + (gadget->u.sli.label->image->pr_height - charheight_of(gadget->u.sli.font)) / 2;
  366. X          }
  367. X       else {
  368. X          ly = y + (charheight_of(gadget->u.sli.font) - gadget->u.sli.label->image->pr_height) / 2;
  369. X          vy = y;
  370. X          }
  371. X       if (gadget->u.sli.label)
  372. X          p = panel_create_item(d->panel, PANEL_SLIDER,
  373. X                             PANEL_LABEL_IMAGE, gadget->image,
  374. X                             PANEL_LABEL_X, x,
  375. X                             PANEL_LABEL_Y, ly,
  376. X                             PANEL_VALUE_X, x + gadget->image->pr_width + 4,
  377. X                             PANEL_VALUE_Y, vy,
  378. X                          0);
  379. X       else
  380. X          p = panel_create_item(d->panel, PANEL_SLIDER,
  381. X                             PANEL_VALUE_X, x,
  382. X                             PANEL_VALUE_Y, y,
  383. X                          0);
  384. X       panel_set(p, PANEL_MIN_VALUE, gadget->u.sli.minimum,
  385. X                   PANEL_MAX_VALUE, gadget->u.sli.maximum,
  386. X                   PANEL_VALUE, gadget->u.sli.initial,
  387. X                   PANEL_VALUE_FONT, gadget->u.sli.font,
  388. X                   PANEL_SHOW_RANGE, gadget->u.sli.range,
  389. X                   PANEL_SHOW_VALUE, gadget->u.sli.value,
  390. X                   PANEL_SLIDER_WIDTH, gadget->u.sli.width,
  391. X                   PANEL_CLIENT_DATA, gadget,
  392. X                PANEL_EVENT_PROC, event_proc,
  393. X                PANEL_NOTIFY_PROC, notify_proc,
  394. X                PANEL_ACCEPT_KEYSTROKE, !d->text_items_exist,
  395. X             0);
  396. X       }
  397. X    else if (gadget->kind == GADGET_CHOICE) {
  398. X       p = panel_create_item(d->panel, PANEL_CHOICE,
  399. X                       PANEL_MARK_IMAGES, gadget->u.cho.mark->image, 0,
  400. X                             PANEL_NOMARK_IMAGES, gadget->u.cho.nomark->image, 0,
  401. X                             PANEL_CLIENT_DATA, gadget,
  402. X                             PANEL_EVENT_PROC, event_proc,
  403. X                             PANEL_NOTIFY_PROC, notify_proc,
  404. X                             PANEL_FEEDBACK, (gadget->u.cho.mode != CHOICE_CURRENT)? PANEL_MARKED : PANEL_NONE,
  405. X                          0);
  406. X       if (gadget->u.cho.mode == CHOICE_CURRENT || gadget->u.cho.mode == CHOICE_CYCLE)
  407. X          panel_set(p, PANEL_DISPLAY_LEVEL, PANEL_CURRENT, 0);
  408. X       else
  409. X          panel_set(p, PANEL_DISPLAY_LEVEL, PANEL_ALL, 0);
  410. X       max_mw = (gadget->u.cho.mode != CHOICE_CURRENT)? max(gadget->u.cho.mark->image->pr_width, gadget->u.cho.nomark->image->pr_width) : -4;
  411. X       max_mh = (gadget->u.cho.mode != CHOICE_CURRENT)? max(gadget->u.cho.mark->image->pr_height, gadget->u.cho.nomark->image->pr_height) : 0;
  412. X       if (gadget->u.cho.label) {
  413. X          lx = x;
  414. X          mx = x + gadget->u.cho.label->image->pr_width + 4;
  415. X          vx = mx + max_mw + 4;
  416. X          if (gadget->u.cho.label->image->pr_height > max_mh)
  417. X             if (gadget->u.cho.label->image->pr_height > gadget->u.cho.ch_height)
  418. X                max_h = gadget->u.cho.label->image->pr_height;
  419. X             else
  420. X                max_h = gadget->u.cho.ch_height;
  421. X          else if (max_mh > gadget->u.cho.ch_height)
  422. X             max_h = max_mh;
  423. X          else
  424. X             max_h = gadget->u.cho.ch_height;
  425. X          ly = y + (max_h - gadget->u.cho.label->image->pr_height) / 2;
  426. X          my = y + (max_h - max_mh) / 2;
  427. X          vy = y + (max_h - gadget->u.cho.ch_height) / 2;
  428. X          }
  429. X       else {
  430. X          mx = x;
  431. X          vx = x + max_mw + 4;
  432. X          max_h = max(max_mh, gadget->u.cho.ch_height);
  433. X          my = y + (max_h - max_mh) / 2;
  434. X          vy = y + (max_h - gadget->u.cho.ch_height) / 2;
  435. X          }
  436. X       if (gadget->u.cho.mode == CHOICE_VERTICAL) {
  437. X          ly = y;
  438. X          for (i = 0, vy = y, cv = gadget->u.cho.value; cv; i++, cv = cv->next) {
  439. X             if (max_mh > cv->label->image->pr_height)
  440. X                panel_set(p, PANEL_CHOICE_IMAGE, i, cv->label->image,
  441. X                         PANEL_CHOICE_X, i, vx,
  442. X                         PANEL_CHOICE_Y, i, vy + (max_mh - cv->label->image->pr_height) / 2,
  443. X                         PANEL_MARK_X, i, mx,
  444. X                         PANEL_MARK_Y, i, vy,
  445. X                          0);
  446. X             else
  447. X                panel_set(p, PANEL_CHOICE_IMAGE, i, cv->label->image,
  448. X                         PANEL_CHOICE_X, i, vx,
  449. X                         PANEL_CHOICE_Y, i, vy,
  450. X                         PANEL_MARK_X, i, mx,
  451. X                         PANEL_MARK_Y, i, vy + (cv->label->image->pr_height - max_mh) / 2,
  452. X                          0);
  453. X             vy += max(max_mh, cv->label->image->pr_height) + 4;
  454. X             }
  455. X          }
  456. X       else {
  457. X          for (i = 0, cv = gadget->u.cho.value; cv; cv = cv->next, i++) {
  458. X             panel_set(p, PANEL_CHOICE_IMAGE, i, cv->label->image,
  459. X                          PANEL_CHOICE_X, i, vx,
  460. X                          PANEL_CHOICE_Y, i, vy + (gadget->u.cho.ch_height - cv->label->image->pr_height) / 2,
  461. X                       0);
  462. X             if (gadget->u.cho.mode != CHOICE_CURRENT)
  463. X                panel_set(p, PANEL_MARK_X, i, mx,
  464. X                             PANEL_MARK_Y, i, my,
  465. X                          0);
  466. X             if (gadget->u.cho.mode == CHOICE_HORIZONTAL) {
  467. X                mx += max_mw + cv->label->image->pr_width + 8;
  468. X                vx += max_mw + cv->label->image->pr_width + 8;
  469. X                }
  470. X             }
  471. X          }
  472. X       if (gadget->u.cho.label)
  473. X          panel_set(p, PANEL_LABEL_IMAGE, gadget->u.cho.label->image,
  474. X                     PANEL_LABEL_X, lx,
  475. X                     PANEL_LABEL_Y, ly,
  476. X                  0);
  477. X       }
  478. X    else if (gadget->kind == GADGET_TEXT) {
  479. X       if (gadget->u.tex.label == NULL)
  480. X          vy = y;
  481. X       else if (gadget->u.tex.label->is_icon)
  482. X          if (gadget->u.tex.label->image->pr_height > gadget->u.tex.font->pf_defaultsize.y) {
  483. X             ly = y;
  484. X             vy = y + (gadget->height - gadget->u.tex.font->pf_defaultsize.y) / 2;
  485. X             }
  486. X          else {
  487. X             ly = y + (gadget->height - gadget->u.tex.label->image->pr_height) / 2;
  488. X             vy = y;
  489. X             }
  490. X       else
  491. X          if (gadget->u.tex.label->font->pf_defaultsize.y > gadget->u.tex.font->pf_defaultsize.y) {
  492. X             ly = y;
  493. X             vy = y + (baseline_of(gadget->u.tex.label->font) - baseline_of(gadget->u.tex.font));
  494. X             }
  495. X          else {
  496. X             ly = y + (baseline_of(gadget->u.tex.font) - baseline_of(gadget->u.tex.label->font));
  497. X             vy = y;
  498. X             }
  499. X       if (gadget->u.tex.label)
  500. X          p = panel_create_item(d->panel, PANEL_TEXT,
  501. X                             PANEL_LABEL_IMAGE, gadget->image,
  502. X                             PANEL_LABEL_X, x,
  503. X                               PANEL_LABEL_Y, ly,
  504. X                          0);
  505. X       else
  506. X          p = panel_create_item(d->panel, PANEL_TEXT, 0);
  507. X       panel_set(p, PANEL_VALUE_X, gadget->u.tex.label? x + 4 + gadget->image->pr_width : x,
  508. X                PANEL_VALUE_Y, vy,
  509. X                PANEL_VALUE_DISPLAY_LENGTH, gadget->u.tex.display_len,
  510. X                PANEL_VALUE_STORED_LENGTH, gadget->u.tex.retain_len,
  511. X                PANEL_VALUE_FONT, gadget->u.tex.font,
  512. X               PANEL_NOTIFY_LEVEL, PANEL_ALL,
  513. X               PANEL_CLIENT_DATA, gadget,
  514. X               PANEL_EVENT_PROC, event_proc,
  515. X               PANEL_NOTIFY_PROC, notify_proc,
  516. X                0);
  517. X       }
  518. X    gadget->panel_item = p;
  519. X}
  520. END_OF_FILE
  521. if test 19133 -ne `wc -c <'objects.c'`; then
  522.     echo shar: \"'objects.c'\" unpacked with wrong size!
  523. fi
  524. # end of 'objects.c'
  525. fi
  526. if test -f 'samples/vt100/out.c' -a "${1}" != "-c" ; then 
  527.   echo shar: Will not clobber existing file \"'samples/vt100/out.c'\"
  528. else
  529. echo shar: Extracting \"'samples/vt100/out.c'\" \(19613 characters\)
  530. sed "s/^X//" >'samples/vt100/out.c' <<'END_OF_FILE'
  531. X/*
  532. X * vtem - A termcap driven VT100 emulator for BSD Unix
  533. X *
  534. X * $Header: /home/src/local/vttool/RCS/out.c,v 1.2 89/02/08 16:08:10 jqj Exp $
  535. X *
  536. X * $Log:    out.c,v $
  537. X * Revision 1.2  89/02/08  16:08:10  jqj
  538. X * Many changes for better emulation.  Emulator now passes most vttest tests
  539. X * with the exception of double height/width lines and special characters.
  540. X * Major changes include:
  541. X * 1/ respond to terminal inquiries
  542. X * 2/ reasonable handling of 132-column mode (truncate lines if no room).  Full
  543. X *     support if CO >= 132 in termcap.
  544. X * 3/ correct handling of autowrap (e.g. "x" in col 80 then cursor up => no wrap)
  545. X * 4/ support for VT102 features (I/D line, D char, IRM, terminal inquiry)
  546. X * 5/ newline mode
  547. X * 6/ \E[5r should set scrolling region to [5,24]
  548. X * 7/ correct handling of character sets in VT52 mode
  549. X * 8/ correct handling of most control characters
  550. X * 9/ various miscellaneous bugs in the emulation
  551. X * 
  552. X * Version 1.1+gnu1+bgb
  553. X * Fixed handling of ^[[0;0r - clear scroll region barnett@ge-crd.arpa
  554. X * added mechanism to approximate the VT52 Special Graphics Set
  555. X * ^[Fn where  \0157 <= n <= \0176
  556. X *
  557. X * Version 1.1+gnu1
  558. X * Bug fixes by hoptoad!gnu for version 1.1+gnu1:
  559. X * Don't walk past the end of the 'tabs' array if we are in column 81.
  560. X * There may still be a few column 81 bugs in here.
  561. X *
  562. X * Public domain software.
  563. X * Written by Leif Samuelsson (leif@erisun) in December, 1985
  564. X */
  565. X
  566. X#include "vtem.h"
  567. X
  568. Xtypedef Bool int;
  569. Xtypedef enum { NORMAL, GRAPHICS } char_set;
  570. X
  571. Xstatic int    row, col, save_row, save_col, top_margin, bottom_margin;
  572. Xstatic char_set    g0_set, g1_set;
  573. Xstatic Bool    blink, bold, reverse, underline,
  574. X        save_blink, save_bold, save_reverse, save_underline,
  575. X        origin_mode, vt52_mode, wrap_mode,
  576. X        newline_mode, insert_mode, echo_mode,
  577. X        cursor_key_mode, keypad_app_mode,
  578. X        shift_out, need_wrap;
  579. Xstatic int    wrap_column;    /* 80 or 132 */
  580. Xstatic short tabs[132];
  581. Xstatic FILE *f;
  582. Xstatic int arg[10], argno;
  583. Xstatic char *answerback = "\r";
  584. X
  585. X/* arow is absolute row, taking top_margin into account */
  586. X#define arow    (row + (origin_mode ? (top_margin - 1) : 0))
  587. X
  588. X
  589. X/* nextch - read output and interpret control characters.
  590. X *        Return first non-control character, or EOF or CAN on error
  591. X */
  592. Xstatic
  593. Xint nextch()
  594. X{
  595. Xregister int ch;
  596. X
  597. X    while ((ch = getc(f)) != EOF) {
  598. X    switch (ch) {
  599. X        case '\0':            /* Ignore nulls and DELs */
  600. X        case '\177':
  601. X            break;
  602. X        case '\005':        /* Dumb answerback */
  603. X            write(master,answerback,strlen(answerback));
  604. X            break;
  605. X        case '\007':        /* Bell */
  606. X        ring_bell(); break;
  607. X        case '\b':            /* BackSpace */
  608. X            need_wrap = 0;
  609. X            if (col > 1) {
  610. X            if (--col < CO)
  611. X                backspace();
  612. X            } break;
  613. X        case '\t':            /* Tab */
  614. X        while (col < wrap_column && !tabs[col++])
  615. X            need_wrap = 0;
  616. X        set_cursor(col-1, arow-1); break;
  617. X        case '\n':            /* Line Feed */
  618. X        case '\013':        /* VT */
  619. X        case '\014':        /* FF */
  620. X            if (newline_mode) 
  621. X            do_newline();
  622. X            else do_linefeed();
  623. X            break;
  624. X
  625. X        case '\r':            /* Carriage Return */
  626. X        need_wrap = 0;
  627. X        if (col > 1) {
  628. X            col = 1;
  629. X            cr();
  630. X        } break;
  631. X        case '\016':
  632. X        shift_out = 1; break;
  633. X        case '\017':
  634. X            shift_out = 0; break;
  635. X        case '\032':        /* SUB -- treat as CAN */
  636. X        ch = '\030';        /* and print error indicator */
  637. X        do_printing('a', GRAPHICS);
  638. X        default:
  639. X        return(ch);
  640. X    }
  641. X    if (f->_cnt == 0)
  642. X        fflush(stdout);
  643. X    }
  644. X    return(ch);
  645. X}
  646. X
  647. X/* handle_output - Main loop of output process.
  648. X *           Reads and dispatches characters from output stream.
  649. X * Called from main() in a lower fork.
  650. X */
  651. Xhandle_output()
  652. X{
  653. Xregister int ch;
  654. X
  655. X    (void) close(0);
  656. X    if ((f = fdopen(master, "r")) == (FILE *) 0) {
  657. X    fprintf(stderr, "handle_output: Can't read from shell\r\n");
  658. X    exit(1);
  659. X    }
  660. X    do_reset();
  661. X    if (vttype == VT52)
  662. X    vt52_mode = 1;
  663. X    while ((ch = nextch()) != EOF) {
  664. X    if (ch == '\033') {        /* Escape character */
  665. X        if (vt52_mode)
  666. X        do_vt52_escape();
  667. X        else
  668. X        do_ansi_escape();
  669. X    }
  670. X    else if (ch >= ' ')        /* Printing character */
  671. X        do_printing(ch,(shift_out ? g1_set : g0_set));
  672. X    if (f->_cnt == 0)
  673. X        fflush(stdout);
  674. X    }
  675. X    fclose(f);
  676. X    exit(0);
  677. X}
  678. X
  679. X
  680. X/* do_printing - process a printing character.
  681. X * ch -- the ascii character to be printed.
  682. X * charset -- NORMAL or GRAPHICS
  683. X */
  684. Xstatic do_printing(ch, charset)
  685. Xchar ch;
  686. Xchar_set charset;
  687. X{
  688. X    /* on some terminals, we could be smarter about graphics characters */
  689. X    if (charset == GRAPHICS) {
  690. X    if (ch >= '_')
  691. X        ch = " *#HFCLo+NV+++++---__++++!<>P##. "[ch - '_'];
  692. X    }
  693. X    if (need_wrap) {        /* last action wrote to wrap column */
  694. X    col = 1;
  695. X    need_wrap = 0;
  696. X    set_cursor(col-1, arow-1);
  697. X    do_linefeed();
  698. X    }
  699. X    if (col == wrap_column) {    /* last column of current display */
  700. X    if (arow < LI && col <= CO)
  701. X        putchar(ch);    /* Must ignore last pos to avoid scroll */
  702. X    set_cursor(col-1, arow-1);
  703. X    if (wrap_mode)
  704. X        need_wrap = 1;
  705. X    }
  706. X    else {
  707. X    if (col <= CO && (col < CO || arow < LI)) {
  708. X        if (insert_mode)
  709. X        insert_char(ch);    /* maybe make room, then print */
  710. X        else putchar(ch);        /* just print it */
  711. X        if (col == CO)        /* might have caused a wrap if AM */
  712. X        set_cursor(col-1, arow-1);    /* put it back where it was */
  713. X    }
  714. X    col++;
  715. X    }
  716. X}
  717. X
  718. X/* do_ansi_escape - reads and interprets an ANSI escape sequence
  719. X */
  720. X
  721. Xstatic do_ansi_escape()
  722. X{
  723. Xregister int ch;
  724. X
  725. X    if ((ch = nextch()) == EOF)
  726. X    return;
  727. X    switch (ch) {
  728. X    case '\030':            /* CANCEL */
  729. X        break;
  730. X    case '#': 
  731. X        do_hash();
  732. X        break;
  733. X    case '=':            /* we ignore keypad_app_mode */
  734. X        keypad_app_mode = 0; break;
  735. X    case '>':
  736. X        keypad_app_mode = 1; break;
  737. X    case '(':
  738. X    case ')':
  739. X        do_character_sets(ch); break;
  740. X    case '7':            /* save cursor */
  741. X        save_row = row;
  742. X        save_col = col;
  743. X        save_blink = blink;
  744. X        save_bold = bold;
  745. X        save_reverse = reverse;
  746. X        save_underline = underline;
  747. X        break;
  748. X    case '8':            /* resort cursor */
  749. X        row = save_row;        /* if no previous SAVE, use default */
  750. X        col = save_col;
  751. X        set_cursor(col-1, arow-1);
  752. X        if (blink = save_blink)
  753. X        start_blink();
  754. X        if (bold = save_bold)
  755. X        start_bold();
  756. X        if (reverse = save_reverse)
  757. X        start_reverse();
  758. X        if (underline = save_underline)
  759. X        start_underline();
  760. X        break;
  761. X    case 'D':            /* cursor down, with scroll */
  762. X        do_linefeed(); break;
  763. X    case 'E':            /* CRLF, with scroll */
  764. X        do_newline(); break;
  765. X    case 'H':            /* set tab in current column */
  766. X        if (col <= sizeof (tabs)/sizeof (*tabs))
  767. X            tabs[col-1] = 1; break;
  768. X    case 'M':            /* cursor up, with scroll */
  769. X        do_reverse_lf(); break;
  770. X    case 'Z':
  771. X        do_device_attributes(); break;
  772. X    case '[':
  773. X        do_csi(); break;
  774. X    case 'c':
  775. X        do_reset();
  776. X        ring_bell(); break;
  777. X    }
  778. X}
  779. X
  780. X/* do_csi - the real ANSI interpreter
  781. X */
  782. Xstatic do_csi()
  783. X{
  784. Xregister int i, ch;
  785. Xint private;
  786. X
  787. X    if ((ch = nextch()) == EOF || ch == '\030')
  788. X    return;
  789. X
  790. X    /* Check if private VT100 esc sequence */
  791. X    private = 0;
  792. X    if (ch == '?') {
  793. X    private = 1;
  794. X    if ((ch = nextch()) == EOF || ch == '\030')
  795. X        return;
  796. X    }
  797. X
  798. X    /* Parse arguments */
  799. X    argno = 0;
  800. X    while ((ch >= '0' && ch <= '9') || ch == ';') {
  801. X    arg[argno] = 0;
  802. X    while (ch >= '0' && ch <= '9') {
  803. X        arg[argno] = arg[argno] * 10 + (ch - '0');
  804. X        if ((ch = nextch()) == EOF || ch == '\030')
  805. X        return;
  806. X    }
  807. X    if (ch == ';') {
  808. X        if ((ch = nextch()) == EOF || ch == '\030')
  809. X        return;
  810. X    }
  811. X    argno++;
  812. X    }
  813. X
  814. X    if (private) {
  815. X    switch (ch) {
  816. X        case 'h':
  817. X        do_set_mode(private,1);
  818. X        break;
  819. X        case 'l':
  820. X        do_set_mode(private,0);
  821. X        break;
  822. X    }
  823. X    }
  824. X    else {
  825. X    switch (ch) {
  826. X        case 'A':
  827. X        need_wrap = 0;
  828. X        i = (argno == 1 && arg[0] > 0) ? arg[0] : 1;
  829. X        while (i-- && arow > 1 && arow != top_margin) {
  830. X            cursor_up();
  831. X            row--;
  832. X        } break;
  833. X
  834. X        case 'B':
  835. X        need_wrap = 0;
  836. X        i = (argno == 1 && arg[0] > 0) ? arg[0] : 1;
  837. X        while (i-- && arow < 24 && arow != bottom_margin) {
  838. X            cursor_down();
  839. X            row++;
  840. X        } break;
  841. X
  842. X        case 'C':
  843. X        i = (argno == 1 && arg[0] > 0) ? arg[0] : 1;
  844. X        while (i-- && col < wrap_column) {
  845. X            need_wrap = 0;
  846. X            if (col++ < CO)
  847. X            cursor_right();
  848. X        } break;
  849. X
  850. X        case 'D':
  851. X        need_wrap = 0;
  852. X        i = (argno == 1 && arg[0] > 0) ? arg[0] : 1;
  853. X        while (i-- && col > 1) {
  854. X            if (--col < CO)
  855. X            backspace();
  856. X        } break;
  857. X
  858. X        case 'H':
  859. X        case 'f':
  860. X        do_set_cursor(); break;
  861. X        case 'J':
  862. X        do_erase_in_display(); break;
  863. X        case 'K':
  864. X        do_erase_in_line(); break;
  865. X        case 'L':
  866. X        do_insert_line(); break;
  867. X        case 'M':
  868. X        do_delete_line(); break;
  869. X        case 'P':
  870. X        do_delete_char(); break;
  871. X        case 'c':
  872. X            do_device_attributes(); break;
  873. X        case 'g':
  874. X            do_clear_tabs(); break;
  875. X        case 'h':
  876. X        do_set_mode(private,1); break;
  877. X        case 'l':
  878. X        do_set_mode(private,0); break;
  879. X        case 'm':
  880. X        do_attributes(); break;
  881. X        case 'n':
  882. X            do_device_status_report(private); break;
  883. X        case 'r':
  884. X        do_set_scroll_region(); break;
  885. X        case 'x':
  886. X        /* Request Terminal Parameters--make some up for now */
  887. X        if (argno == 0 || arg[0] == 0)
  888. X            write(master,"\033[2;1;2;120;120;1;0x",20);
  889. X        else if (arg[0] == 1)
  890. X            write(master,"\033[3;1;2;120;120;1;0x",20);
  891. X        break;
  892. X    }
  893. X    }
  894. X}
  895. X
  896. X/* do_set_mode - process \E[<#;...>h \E[<#;...>l
  897. X * private == 1 -- call was \E[?...
  898. X * setit == 1 -- call was \E[...h (set_mode) rather than \E[...l (reset_mode)
  899. X */
  900. Xstatic do_set_mode(private,setit)
  901. XBool private, setit;
  902. X{
  903. X    int i;
  904. X    for (i = 0; i < argno; i++) {
  905. X    if (private) switch (arg[i]) {
  906. X        case 1:            /* DECCKM */
  907. X        cursor_key_mode = setit; break;
  908. X        case 2:            /* DECANM */
  909. X        vt52_mode = !setit; break;
  910. X        case 3:            /* DECCOLM */
  911. X        clear_screen();
  912. X        row = 1; col = 1;
  913. X        top_margin = 1; bottom_margin = 24;
  914. X        set_cursor(col-1, arow-1);
  915. X        wrap_column = setit ? 132 : 80;
  916. X        break;
  917. X        case 6:            /* DECOM */
  918. X        origin_mode = setit; break;
  919. X        case 7:            /* DECAWN */
  920. X        wrap_mode = setit; break;
  921. X        case 12:            /* echo -- not implemented */
  922. X        echo_mode = setit; break;
  923. X        default:            /* DECSNM, DECARM, DECPFF, DECPEX */
  924. X        break;
  925. X    }
  926. X    else switch (arg[i]) {        /* ANSI sequences */
  927. X        case 4:            /* IRM -- insert/replace mode */
  928. X            if (vttype == VT102) {
  929. X            insert_mode = setit;
  930. X            set_insert_mode(setit);
  931. X        }
  932. X        break;
  933. X        case 20:            /* LNM - linefeed/newline mode */
  934. X        newline_mode = setit; break;
  935. X    }
  936. X    }
  937. X}
  938. X
  939. X
  940. X/* do_vt52_escape - interprets VT52 escape sequences
  941. X * note that if vttype==VT52 we provide a partial emulation of a VT52,
  942. X * just as a VT100 does, not a real VT52.
  943. X */
  944. Xstatic do_vt52_escape()
  945. X{
  946. Xregister int ch;
  947. X
  948. X    if ((ch = nextch()) == EOF)
  949. X    return;
  950. X    switch (ch) {
  951. X    case '=':            /* we ignore keypad_app_mode */
  952. X        keypad_app_mode = 0; break;
  953. X    case '>':
  954. X        keypad_app_mode = 1; break;
  955. X    case '<':
  956. X        if (vttype != VT52)    /* can we handle VT100 sequences? */
  957. X            vt52_mode = 0;
  958. X        break;
  959. X    case 'A':
  960. X        if (row > 1) {
  961. X            need_wrap = 0;
  962. X            cursor_up();
  963. X            row--;
  964. X        } break;
  965. X    case 'B':
  966. X        if (row < bottom_margin-top_margin+1) {
  967. X            need_wrap = 0;
  968. X            cursor_down();
  969. X            row++;
  970. X        } break;
  971. X    case 'C':
  972. X        if (col < wrap_column) {
  973. X            need_wrap = 0;
  974. X            cursor_right();
  975. X            col++;
  976. X        } break;
  977. X    case 'D':
  978. X        if (col > 1) {
  979. X            need_wrap = 0;
  980. X            if (--col < CO)
  981. X            backspace();
  982. X        } break;
  983. X    case 'H':
  984. X        row = col = 1;
  985. X        need_wrap = 0;
  986. X        set_cursor(col-1, arow-1); break;
  987. X    case 'I':
  988. X        do_reverse_lf(); break;
  989. X    case 'J':
  990. X        clear_eos(); break;
  991. X    case 'K':
  992. X        clear_eol(col-1, arow-1); break;
  993. X    case 'Y':
  994. X        do_vt52_set_cursor(); break;
  995. X        case 'F':
  996. X        g0_set = g1_set = GRAPHICS; break;
  997. X    case 'G':
  998. X        g0_set = g1_set = NORMAL; break;
  999. X    case 'Z':        /* identify as VT52 */
  1000. X        write(master,"\033/Z",3); break;
  1001. X    }
  1002. X}
  1003. X
  1004. Xstatic do_set_cursor()
  1005. X{
  1006. X    if (arg[0] == 0)
  1007. X    arg[0]++;
  1008. X    if (arg[1] == 0)
  1009. X    arg[1]++;
  1010. X    switch (argno) {
  1011. X    case 0:
  1012. X        arg[0] = 1;
  1013. X        /* Fall through */
  1014. X
  1015. X    case 1:
  1016. X        arg[1] = 1;
  1017. X        /* Fall through... */
  1018. X
  1019. X    case 2:
  1020. X        if (arg[0] > 24)
  1021. X        arg[0] = 24;
  1022. X        if (arg[1] > wrap_column)
  1023. X        arg[1] = wrap_column;
  1024. X        if (row != arg[0] || col != arg[1])
  1025. X        need_wrap = 0;        /* bizarre */
  1026. X        row = arg[0];
  1027. X        col = arg[1];
  1028. X        set_cursor(col-1, arow-1);
  1029. X        break;
  1030. X    }
  1031. X}
  1032. X
  1033. Xstatic do_vt52_set_cursor()
  1034. X{
  1035. Xregister int ch1, ch2;
  1036. X
  1037. X    if ((ch1 = nextch()) == EOF)
  1038. X    return;
  1039. X    if ((ch2 = nextch()) == EOF)
  1040. X    return;
  1041. X    ch1 -= 0x1f;
  1042. X    ch2 -= 0x1f;
  1043. X    if (ch1 >= 1 && ch1 <= 24 && ch2 >= 1 && ch2 <= 80) {
  1044. X        if (row != ch1 || col != ch2)
  1045. X        need_wrap = 0;
  1046. X        row = ch1;
  1047. X        col = ch2;
  1048. X        set_cursor(col-1, arow-1);
  1049. X    }
  1050. X}
  1051. X
  1052. X/* do_erase_in_display - process \E[<#>J
  1053. X */
  1054. Xstatic do_erase_in_display()
  1055. X{
  1056. X    switch (argno) {
  1057. X    case 0:
  1058. X        arg[0] = 0;
  1059. X        argno++;
  1060. X        /* Fall through */
  1061. X    case 1:
  1062. X        switch (arg[0]) {
  1063. X        case 0:
  1064. X            clear_eos();
  1065. X            break;
  1066. X        case 1:
  1067. X            clear_bos(col-1, arow-1);
  1068. X            break;
  1069. X        case 2:
  1070. X            clear_screen();
  1071. X            set_cursor(col-1, arow-1);
  1072. X            break;
  1073. X        }
  1074. X        break;
  1075. X    }
  1076. X}
  1077. X
  1078. X/* do_erase_in_line - process \E[<#>K
  1079. X */
  1080. Xstatic do_erase_in_line()
  1081. X{
  1082. X    switch(argno) {
  1083. X    case 0:
  1084. X        arg[0] = 0;
  1085. X        argno++;
  1086. X        /* fall through */
  1087. X    case 1:
  1088. X        switch (arg[0]) {
  1089. X        case 0:
  1090. X            clear_eol(col-1, arow-1);
  1091. X            break;
  1092. X        case 1:
  1093. X            clear_bol(col-1, arow-1);
  1094. X            break;
  1095. X        case 2:
  1096. X            cr();
  1097. X            clear_eol(0, arow-1);
  1098. X            set_cursor(col-1, arow-1);
  1099. X            break;
  1100. X        } break;
  1101. X    }
  1102. X}
  1103. X
  1104. Xstatic do_clear_tabs()
  1105. X{
  1106. Xregister int i;
  1107. X
  1108. X    if (argno == 0)
  1109. X    arg[argno++] = 0;
  1110. X    switch (arg[0]) {
  1111. X    case 0:
  1112. X        if (col <= sizeof (tabs)/sizeof (*tabs))
  1113. X            tabs[col-1] = 0; break;
  1114. X    case 3:
  1115. X        for (i = 0; i < sizeof (tabs)/sizeof (*tabs); i++)
  1116. X        tabs[i] = 0;    /* should we stop at wrap_column? */
  1117. X        break;
  1118. X    } 
  1119. X}
  1120. X
  1121. X/* do_attributes - process \E[<#...>m
  1122. X */
  1123. Xstatic do_attributes()
  1124. X{
  1125. Xregister int i;
  1126. X
  1127. X    if (argno == 0) {
  1128. X    arg[0] = 0;
  1129. X    argno++;
  1130. X    }
  1131. X    for (i=0; i<argno; i++) {
  1132. X    switch (arg[i]) {
  1133. X        case 0:
  1134. X        end_attributes();
  1135. X        bold = underline = blink = reverse = 0;
  1136. X        break;
  1137. X        case 1:
  1138. X        start_bold();
  1139. X        bold = 1; break;
  1140. X
  1141. X        case 4:
  1142. X        start_underline();
  1143. X        underline = 1; break;
  1144. X
  1145. X        case 5:
  1146. X        start_blink();
  1147. X        blink = 1; break;
  1148. X
  1149. X        case 7:
  1150. X        start_reverse();
  1151. X        reverse = 1; break;
  1152. X    }
  1153. X    }
  1154. X}
  1155. X
  1156. Xstatic do_set_scroll_region()
  1157. X{
  1158. X    switch (argno) {
  1159. X    case 0:
  1160. X        arg[0] = 1;
  1161. X        /* Fall through */
  1162. X    case 1:
  1163. X        arg[1] = 24;
  1164. X        argno = 2;
  1165. X        /* Fall through */
  1166. X    case 2:
  1167. X        if (arg[0] == 0 && arg[1] == 0) {    /* per bgb */
  1168. X        arg[0] = 1; arg[1] = 24;
  1169. X        } else {
  1170. X        if (arg[0] == 0)
  1171. X          arg[0] = 1;
  1172. X        if (arg[1] == 0)
  1173. X          arg[1] = 1;
  1174. X        }
  1175. X        if (arg[0] < arg[1]) {    /* region must be at least 2 lines */
  1176. X        top_margin = arg[0];
  1177. X        bottom_margin = arg[1];
  1178. X        col = row = 1;
  1179. X        need_wrap = 0;
  1180. X        set_cursor(col-1, arow-1);
  1181. X        }
  1182. X        break;
  1183. X    }
  1184. X}
  1185. X
  1186. X/* do_newline - next line, column 0, with possible scroll
  1187. X */
  1188. Xstatic do_newline()
  1189. X{
  1190. X        if (col > 1) {
  1191. X        col = 1;
  1192. X        cr();
  1193. X        need_wrap = 0;
  1194. X        }
  1195. X        do_linefeed();
  1196. X}
  1197. X
  1198. X/* do_linefeed - next line, same column, with possible scroll
  1199. X * (note -- no cursor down if at bottom of screen below scrolling region)
  1200. X */
  1201. Xstatic do_linefeed()
  1202. X{
  1203. X    if (arow == bottom_margin) {
  1204. X     need_wrap = 0;
  1205. X    if (bottom_margin < LI || top_margin > 1) {
  1206. X        scroll_region(top_margin-1, bottom_margin-1, TRUE);
  1207. X        set_cursor(col-1, arow-1);
  1208. X    }
  1209. X    else
  1210. X        linefeed();        /* assumed to cause fullscreen scroll */
  1211. X    }
  1212. X    else if (arow < 24) {    /* don't scroll if below scrolling region */
  1213. X     need_wrap = 0;
  1214. X    row++;
  1215. X    linefeed();
  1216. X    }
  1217. X}
  1218. X
  1219. X/* do_reverse_lf - previous line, same column, with possible scroll
  1220. X */
  1221. Xstatic do_reverse_lf()
  1222. X{
  1223. X    if (arow == top_margin) {
  1224. X     need_wrap = 0;
  1225. X    scroll_region(top_margin-1, bottom_margin-1, FALSE);
  1226. X    set_cursor(col-1, arow-1);
  1227. X    }
  1228. X    else if (arow > 1) {    /* don't scroll if above scrolling region */
  1229. X     need_wrap = 0;
  1230. X    row--;
  1231. X    reverse_lf();        /* assumed to cause fullscreen scroll */
  1232. X    }
  1233. X}
  1234. X
  1235. X/* do_hash - process \E#<#>.  Only DECALN -- screen alignment display
  1236. X * functions not implemented include double hight and double width lines!
  1237. X */
  1238. Xstatic do_hash()
  1239. X{
  1240. Xregister int ch, i, j;
  1241. Xint maxch;
  1242. X
  1243. X    if ((ch = nextch()) == EOF)
  1244. X    return;
  1245. X    switch(ch) {
  1246. X    case '8':        /* screen alignment display */
  1247. X        set_cursor(0, 0);
  1248. X        if ((maxch = wrap_column) > CO) maxch = CO;
  1249. X        for (i=1; i<24; i++) {
  1250. X        for (j=maxch; j>0; j--)
  1251. X            putchar('E');
  1252. X        set_cursor(0, i);
  1253. X        }
  1254. X        if (LI <= 24 && CO <= maxch)
  1255. X        maxch--;        /* avoid last space on display */
  1256. X        for (j=maxch; j>0; j--)
  1257. X        putchar('E');
  1258. X        top_margin = 1;
  1259. X        bottom_margin = 24;        /* at least on my VT102... */
  1260. X        row = col = 1;
  1261. X        set_cursor(col-1, arow-1);
  1262. X        break;
  1263. X    }         
  1264. X}
  1265. X
  1266. X/* do_characters_sets - Not fully implemented
  1267. X */
  1268. Xstatic do_character_sets(ch)
  1269. Xregister int ch;
  1270. X{
  1271. Xregister int ch2;
  1272. X
  1273. X    if ((ch2 = nextch()) == EOF)
  1274. X    return;
  1275. X    switch (ch2) {
  1276. X    case 'A':
  1277. X    case 'B':
  1278. X        if (ch == '(')
  1279. X            g0_set = NORMAL;
  1280. X        else
  1281. X            g1_set = NORMAL;
  1282. X        break;
  1283. X    case '0':
  1284. X        if (ch == '(')
  1285. X            g0_set = GRAPHICS;
  1286. X        else
  1287. X            g1_set = GRAPHICS;
  1288. X        break;
  1289. X    }
  1290. X}
  1291. X
  1292. X/* do_reset - Reset emulator and screen
  1293. X */
  1294. Xstatic do_reset()
  1295. X{
  1296. Xregister int i;
  1297. X
  1298. X    clear_screen();
  1299. X    row = 1;
  1300. X    col = 1;
  1301. X    top_margin = 1;
  1302. X    bottom_margin = 24;
  1303. X    origin_mode = 0;
  1304. X    vt52_mode = (vttype == VT52);    /* stuck in VT52 mode? */
  1305. X    wrap_mode = 1;
  1306. X    newline_mode = 0;
  1307. X    insert_mode = 0;
  1308. X    echo_mode = 0;
  1309. X    cursor_key_mode = 0;
  1310. X    keypad_app_mode = 0;
  1311. X    wrap_column = 80;
  1312. X    g0_set = NORMAL;
  1313. X    g1_set = NORMAL;
  1314. X    shift_out = 0;
  1315. X    need_wrap = 0;
  1316. X    end_attributes();
  1317. X    set_insert_mode(0);
  1318. X    bold = underline = blink = reverse = 0;
  1319. X    save_bold = save_underline = save_blink = save_reverse = 0;
  1320. X    save_row = save_col = 1;        /* VT102 goes home if none saved */
  1321. X    for (i=0; i<132; i++)
  1322. X    tabs[i] = ((i/8)*8 == i);
  1323. X}
  1324. X
  1325. X/* do_insert_line - VT102 only
  1326. X * insert lines at the cursor, moving the current line down.  Note that
  1327. X * on a VT102 this is a no-op if the cursor is outside the scrolling region.
  1328. X */
  1329. Xstatic do_insert_line()
  1330. X{
  1331. X    int i;
  1332. X    if (vttype != VT102 || arow < top_margin || arow > bottom_margin)
  1333. X    return;
  1334. X    if (argno==0 || arg[0] == 0) arg[0] = 1;
  1335. X    for (i = 0; i < arg[0]; i++)
  1336. X        scroll_region(arow-1,bottom_margin-1, FALSE);
  1337. X    set_cursor(col-1,arow-1);
  1338. X}
  1339. X
  1340. X/* do_delete_line - VT102 only
  1341. X * delete the line containing the cursor.  Note that on a VT102 this
  1342. X * is a no-op if the cursor is outside the scrolling region.
  1343. X */
  1344. Xstatic do_delete_line()
  1345. X{
  1346. X    int i;
  1347. X    if (vttype != VT102 || arow < top_margin || arow > bottom_margin)
  1348. X    return;
  1349. X    if (argno==0 || arg[0] == 0) arg[0] = 1;
  1350. X    for (i = 0; i < arg[0]; i++)
  1351. X    scroll_region(arow-1,bottom_margin-1, TRUE);
  1352. X    set_cursor(col-1,arow-1);
  1353. X}
  1354. X
  1355. X/* do_delete_char - VT102 only
  1356. X * delete the character at the cursor.  End of line must fill with
  1357. X * blanks.
  1358. X */
  1359. Xstatic do_delete_char()
  1360. X{
  1361. X    int i;
  1362. X    if (vttype != VT102) return;
  1363. X    if (argno==0 || arg[0] == 0) arg[0] = 1;
  1364. X    if (CO > wrap_column) {
  1365. X    set_cursor(wrap_column,arow-1);
  1366. X    clear_eol(wrap_column-1,arow-1);
  1367. X    set_cursor(col-1,arow-1);
  1368. X    }
  1369. X    for (i = 0; i < arg[0]; i++)
  1370. X    delete_char();
  1371. X}
  1372. X
  1373. X/*
  1374. X * Status reports
  1375. X */
  1376. X
  1377. X/* do_device_status_report - process \E[<#>n and \E[?<#>n
  1378. X */
  1379. Xstatic do_device_status_report(private)
  1380. Xint private;
  1381. X{
  1382. X    char buf[12];
  1383. X    if (argno==0) arg[argno++]=1;
  1384. X    switch (arg[0]) {
  1385. X        case 5:    /* device status */
  1386. X        write(master,"\033[0n",4);    /* terminal is ok */
  1387. X        break;
  1388. X        case 6:    /* cursor position report */
  1389. X        sprintf(buf,"\033[%d;%dR",arow,col);
  1390. X        write(master,buf,strlen(buf));
  1391. X        break;
  1392. X        case 15:    /* printer status */
  1393. X        if (private)        /* say "no printer" */
  1394. X            write(master,"\033[?13n",6);
  1395. X        break;
  1396. X    }
  1397. X}
  1398. X
  1399. X/* do_device_attributes - Device Attributes
  1400. X * say we're a VT100 without AVO or a VT102
  1401. X */
  1402. Xstatic do_device_attributes() {
  1403. X    switch (vttype) {
  1404. X        default:
  1405. X        case VT100:
  1406. X        write(master,"\033[?1;0c",7); break;
  1407. X        case VT102:
  1408. X        write(master,"\033[?6c",5); break;
  1409. X    }
  1410. X}
  1411. X
  1412. X
  1413. END_OF_FILE
  1414. if test 19613 -ne `wc -c <'samples/vt100/out.c'`; then
  1415.     echo shar: \"'samples/vt100/out.c'\" unpacked with wrong size!
  1416. fi
  1417. # end of 'samples/vt100/out.c'
  1418. fi
  1419. echo shar: End of archive 7 \(of 13\).
  1420. cp /dev/null ark7isdone
  1421. MISSING=""
  1422. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  1423.     if test ! -f ark${I}isdone ; then
  1424.     MISSING="${MISSING} ${I}"
  1425.     fi
  1426. done
  1427. if test "${MISSING}" = "" ; then
  1428.     echo You have unpacked all 13 archives.
  1429.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1430. else
  1431.     echo You still need to unpack the following archives:
  1432.     echo "        " ${MISSING}
  1433. fi
  1434. ##  End of shell archive.
  1435. exit 0
  1436.  
  1437. Chuck Musciano            ARPA  : chuck@trantor.harris-atd.com
  1438. Harris Corporation         Usenet: ...!uunet!x102a!trantor!chuck
  1439. PO Box 37, MS 3A/1912        AT&T  : (407) 727-6131
  1440. Melbourne, FL 32902        FAX   : (407) 727-{5118,5227,4004}
  1441.